package com.example.mattrigle;

import java.util.ArrayList;
import java.util.List;

import com.example.mattrigle.CustomAnimation.TimerListener;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;

public class SeekBar {

	// ==========================================================
	// Delegate & Callback
	// ==========================================================
    public abstract interface SeekBarListener {
        public void onSeekBarDragged(SeekBar obj,float progress);
        public void onSeekBarBeginDrag(SeekBar obj,float progress);
        public void onSeekBarDragging(SeekBar obj,float progress);
    }

	//==========================================================
	//constant 
	//==========================================================
	private final int unit_point = 11;
	private final int unitOfFloat = 1;
	private final int labelOfFloat = 3;
	
	//==========================================================
	//Field 
	//==========================================================
    private Drawable thumbDrawable = null;
    private Drawable thumbDrawablePressed = null;
    private Drawable thumb = null;
    private static Drawable labelDrawable = null;
    private static Drawable handDrawable = null;
    private Point cursorPoint = new Point(0,0);
    private Paint inner = new Paint();
    private Paint outer = new Paint();
    private Paint unusedPaint = new Paint();
    private Paint labelPaint = new Paint();
    private Paint unitPaint = new Paint();
    private Paint barPaint = new Paint();
    private Paint sub_barPaint = new Paint();
    private View parent;
    private Context _context;

    private boolean isAppendCursorBG = false;
	private float unit_scale = 1f/(unit_point-1);
	private float text_half_width = 0f;
	private float bar_half_width = 0f;
	private float sub_bar_half_width = 0f;
    private float thumbX,thumbDX;
    private float thumbY,thumbDY;
    private float maxThumbX = 1;
    private float maxThumbY = 1;
    private float minThumbX = 0;
    private float minThumbY = 0;
    private static int labelWidth;
    private static int labelHeight;
    private static int handWidth;
    private static int handHeight;

	//==========================================================
	//Properties 
	//==========================================================
	public static final int HORIZONTAL = 2;
	public static final int VERTICAL = 1;
    private int direction = HORIZONTAL;
	public int getDirection()
	{
		return direction;
	}

    private static int thumbWidth;
    public int getThumbWidth()
    {
    	return thumbWidth;
    }
    private static int thumbHeight;
    public int getThumbHeight()
    {
    	return thumbHeight;
    }

    private boolean hideCursor = false;
    public boolean isHideCursor()
    {
    	return hideCursor;
    }
    
    public void setHideCursor(boolean hideCursor)
    {
    	this.hideCursor = hideCursor;
    }
    
    private int width;
    public int getWidth()
    {
    	return width - ((direction==HORIZONTAL)?thumbWidth:0);
    }
    public void setWidth(int width)
    {
    	width =(width<0)?0:width;
    	this.width = width + ((direction==HORIZONTAL)?thumbWidth:0);
    	calView();
    }

    private float half_line_width = 1f;
    public float getLineWidth()
    {
    	return half_line_width*2;
    }
    public void setLineWidth(int line_width)
    {
    	line_width = line_width<1? 1: line_width;
    	
    	this.half_line_width = line_width/2f;
    }
    
    private int height;
    public int getHeight()
    {
    	return height - ((direction==VERTICAL)?thumbHeight:0);
    }
    public void setHeight(int height)
    {
    	if(height<0)height = 0;
    	this.height = height + ((direction==VERTICAL)?thumbHeight:0);
    	calView();
    }

    private List<SeekBarListener> listerners = new ArrayList<SeekBarListener>();
    public void addListener(SeekBarListener listener)
    {
    	listerners.add(listener);
    }
    public void removeListener(SeekBarListener listener)
    {
    	listerners.remove(listener);
    }

    private SeekBarListener listener;
    public void setOnValueChanged(SeekBarListener listener)
    {
    	this.listener = listener;
    }

	public static final int CURSOR_DIRECTION_L2R = 1;
	public static final int CURSOR_DIRECTION_R2L = 0;
    private int cursor_direction;
	public int getCursorDirection()
	{
		return cursor_direction;
	}
	public void setCursorDirection(int cursor_direction)
	{
		this.cursor_direction = (cursor_direction==CURSOR_DIRECTION_L2R||cursor_direction==CURSOR_DIRECTION_R2L)?cursor_direction:CURSOR_DIRECTION_L2R;
	}

	private float scale = 0.5f;

	public float getScale() {
		return scale;
	}

	public void setScale(float scale) {
		this.scale = scale < 0.1f ?  0.1f : scale>0.6f?0.6f:scale;
	}

	public static final int THEME_YELLOW = 3;
	public static final int THEME_RED = 2;
	public static final int THEME_BLUE = 1;
	public static final int THEME_GREEN = 0;
	public static final int THEME_RED_INVERT = 6;
	public static final int THEME_GREEN_INVERT = 7;
	public static final int THEME_YELLOW_INVERT = 8;
    private int theme;
	public int Theme()
	{
		return theme;
	}

	public void setTheme(int theme) {
		this.theme = (theme == THEME_RED || theme == THEME_BLUE
				|| theme == THEME_GREEN|| theme == THEME_YELLOW 
				|| theme == THEME_RED_INVERT || theme == THEME_GREEN_INVERT
				|| theme == THEME_YELLOW_INVERT) ? theme
				: THEME_BLUE;

		switch (this.theme) {
		case THEME_RED:
			inner.setColor(0xffebd9e2);
			outer.setColor(0xfff886c5);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player3);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player3_pressed);
			break;
		case THEME_BLUE:
			inner.setColor(0xffd9e2eb);
			outer.setColor(0xff86c5f8);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player2);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player2_pressed);
			break;
		case THEME_GREEN:
			inner.setColor(0xffb4e396);
			outer.setColor(0xff6ac453);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player1);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player1_pressed);
			break;
		case THEME_YELLOW:
			inner.setColor(0xfffffca8);
			outer.setColor(0xfffff700);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player4);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player4_pressed);
			break;
		case THEME_RED_INVERT:
			inner.setColor(0xff86c5f8);
			outer.setColor(0xfff886c5);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player3);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player3_pressed);
			break;
		case THEME_GREEN_INVERT:
			inner.setColor(0xff86c5f8);
			outer.setColor(0xff6ac453);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player1);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player1_pressed);
			break;
		case THEME_YELLOW_INVERT:
			inner.setColor(0xff86c5f8);
			outer.setColor(0xfffff700);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player4);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player4_pressed);
			break;
		}
		unusedPaint.setColor(0xffbfbfbf);
		if(labelDrawable==null)
			labelDrawable  = _context.getResources().getDrawable(R.raw.ballon);
		labelWidth = (int)(labelDrawable.getIntrinsicWidth()*(scale+0.2f)/2);
		labelHeight = (int)(labelDrawable.getIntrinsicHeight()*(scale+0.2f)/2);
		thumbWidth = thumbDrawable.getIntrinsicWidth();
		thumbHeight = thumbDrawable.getIntrinsicHeight();
	}
	
	private Point offset = new Point(0,0);
	public void setPosition(int x,int y)
	{
		offset.x = x - ((direction==HORIZONTAL)?thumbWidth/2:width/2);
		offset.y = y - ((direction==VERTICAL)?thumbHeight/2:0);
		calView();
	}
	public Point getPosition()
	{
		return new Point(offset.x + ((direction==HORIZONTAL)?thumbWidth/2:0),offset.y + ((direction==VERTICAL)?thumbHeight/2:0));
	}
	
    private boolean isShowUnit = true;
    public boolean IsShowUnit() {
        return isShowUnit;
    }
    public void setShowUnit(boolean isShowUnit)
    {
    	this.isShowUnit= isShowUnit;
    }
	
    private boolean pressed = false;
    public boolean isDragging() {
        return pressed;
    }

    private float progress = 0.000f;
    public float getProgress(boolean isToggle)
    {
    	return (isToggle)?progress:Math.abs(1f-progress);
    }
    public float getProgress()
    {
    	return (cursor_direction==CURSOR_DIRECTION_L2R)?progress:Math.abs(1f-progress);
    }
    public void setProgress(float progress) 
    {
    	this.progress = progress<0f?0f:progress>1f?1f:progress;
    	this.progress = ((cursor_direction==CURSOR_DIRECTION_L2R)?progress:Math.abs(1f - progress));
    	
    	calView();
    }

    private boolean enable = true;
    public boolean getEnable()
    {
    	return enable;
    }
    public void setEnable(boolean enable)
    {
    	this.enable = enable;
    }

    private boolean hideLabel = true;
    public boolean isHideLabel()
    {
    	return hideLabel;
    }
    public void setHideLabel(boolean hideLabel)
    {
    	this.hideLabel = hideLabel;
    }

    private boolean hideHand = true;
    public boolean isHideHand()
    {
    	return hideHand;
    }
    public void setHideHand(boolean hideHand)
    {
    	this.hideHand = hideHand;
    	if(!hideHand)
    	{
    		if(handDrawable==null)
    		{
    			handDrawable = _context.getResources().getDrawable(R.raw.hand);
    			handWidth = (int)(handDrawable.getIntrinsicWidth()*(scale+0.2f)/2);
    			handHeight = (int)(handDrawable.getIntrinsicHeight()*(scale+0.2f)/2);
    		}
    	}
    }

    private float max_length = 1f;
    public float getMaximumLength()
    {
    	return max_length;
    }
    public void setMaximumLength(float length)
    {
    	this.max_length = length;
    	calView();
    }
    
	//==========================================================
	//Process & Operand Method
	//==========================================================
    private void calView()
    {
        thumbX = (progress*(width - thumbWidth));
        maxThumbX = (cursor_direction==CURSOR_DIRECTION_L2R?(max_length*(width - thumbWidth)):width - thumbWidth);
        minThumbX = (cursor_direction==CURSOR_DIRECTION_R2L?((1f-max_length)*(width - thumbWidth)):0);
    	thumbX = thumbX>maxThumbX?maxThumbX:thumbX < minThumbX?minThumbX:thumbX;
    	
        thumbY = (progress * (height - thumbHeight));
        maxThumbY = (cursor_direction==CURSOR_DIRECTION_L2R?(max_length*(height - thumbHeight)):height - thumbHeight);
        minThumbY = (cursor_direction==CURSOR_DIRECTION_R2L?((1f-max_length)*(height - thumbHeight)):0);
    	thumbY = thumbY>maxThumbY?maxThumbY:thumbY < minThumbY?minThumbY:thumbY;

        switch(direction)
		{
		    case HORIZONTAL:
	            cursorPoint.x = (int)thumbX + offset.x + thumbWidth/2;
	            cursorPoint.y =  (height - thumbHeight) / 2 + offset.y + thumbHeight/2;
		        break;
		    case VERTICAL:
		    	cursorPoint.x = (width - thumbWidth) / 2 + offset.x
				+ thumbWidth / 2;
		    	cursorPoint.y = (int)thumbY + offset.y + thumbHeight / 2;
    			break;
		 }
        
        parent.invalidate();
    }
    
	//==========================================================
	//Constructor
	//==========================================================
    public SeekBar(Context context,View parent,int direction,boolean isAppendCursorBG) {
    	this._context = context;
        this.parent = parent;
        this.isAppendCursorBG = isAppendCursorBG;
        
        this.setTheme(THEME_BLUE);
        this.direction = (direction==VERTICAL||direction==HORIZONTAL)?direction:HORIZONTAL;
        this.setPosition(0, 0);
        this.setCursorDirection(CURSOR_DIRECTION_L2R);
        this.setTextSize(30);
        this.setBarSize(11);
        this.setProgressTextColor(0xff383838);
        this.setBarColor(0xff383838);
        Typeface face = Typeface.createFromAsset(context.getAssets(), "fonts/THA0085.ttf");
        unitPaint.setTypeface(face);
        labelPaint.setTypeface(face);
        labelPaint.setTextSize(40);
        labelPaint.setColor(0xff383838);
    }

	//==========================================================
	//Public Method
	//==========================================================
    public int getCursorX()
    {
    	return cursorPoint.x;
    }
    public int getCursorY()
    {
    	return cursorPoint.y;
    }
    public Point getCursorPoint()
    {
    	return cursorPoint;
    }
    
    public void setTextSize(int size)
    {
        unitPaint.setTextSize(size<11?11:size);
        text_half_width = unitPaint.measureText("0.0")/2f;
    }

    public void setBarSize(int size)
    {
    	barPaint.setTextSize(size<11?11:size);
        //text_half_width = (this.direction==HORIZONTAL)?barPaint.measureText("|")/2f:barPaint.measureText("_")/2f;
        sub_barPaint.setTextSize(size/2<6?6:size/2);
    }

    public void setProgressTextColor(int color)
    {
    	unitPaint.setColor(color);
    }

    public void setBarColor(int color)
    {
    	barPaint.setColor(color);
    }
    
    private boolean iscoverLabel = false;
    public void setCoverLabel(boolean iscoverLabel)
    {
    	this.iscoverLabel = iscoverLabel;
    }

    
    public void setSmoothScale(float aw)
    {
        this.setTextSize(((int)(40*aw*1.1)));
        this.setBarSize(((int)(11*aw*1.1)));
        labelPaint.setTextSize(((int)(40*aw*1.1)));
		labelWidth = (int)(labelDrawable.getIntrinsicWidth()*aw*(scale+0.2f)/2);
		labelHeight = (int)(labelDrawable.getIntrinsicHeight()*aw*(scale+0.2f)/2);
    }
	//==========================================================
	//Animation Field 
	//==========================================================
    private CustomAnimation anim = new CustomAnimation();
    private RectF innerRect = null;
    private RectF outerRect = null;
    private RectF unusedRect = null;
    private float zoom_in_anim = 1f;
    private float zoom_anim = 0f;
    private boolean playing = false;
    private int alpha = 255;
    private int delay = 40;

	//==========================================================
	//Animation Public Method 
	//==========================================================
    public boolean isPlaying()
    {
    	return playing;
    }
    public int getAlpha()
    {
    	return alpha;
    }
 	public void fadeActiveAnimation()
    {
		zoom_anim = zoom_in_anim;
		playing = true;
		anim.setInterval(delay);
		alpha = 0;
		anim.setListener(new TimerListener() {

			@Override
			public void onTimeUpdate(CustomAnimation obj, long totalTime,
					long deltaTime) {
				zoom_anim -= (float) Math.abs(Math.sin(zoom_anim))*0.12;
				alpha = (int) (Math.sin(zoom_in_anim - zoom_anim) * 255);
				if (zoom_anim <= 0.1f) {
					anim.EndAnimation();
					zoom_anim = 0f;
					alpha = 255;
					if (parent != null)
						parent.postInvalidate();
					playing = false;
				} else if (parent != null)
					parent.postInvalidate();
			}
		});
		anim.StartAnimation();
		if(parent!=null)
			parent.postInvalidate();
    }

    // ==========================================================
	// Event Method
	// ==========================================================
	public boolean onTouch(int action, float x, float y) {
		if (enable) {
			switch (direction) {
			case HORIZONTAL:
				if (action == MotionEvent.ACTION_DOWN) {
					int additionWidth = (height - thumbWidth) / 2;
					if (thumbX - additionWidth + offset.x <= x
							&& x <= thumbX + offset.x + thumbWidth
									+ additionWidth && y >= offset.y
							&& y <= height + offset.y) {
						pressed = true;
						thumbDX = (int) (x - thumbX);
						cursorPoint.x = (int)thumbX + offset.x + thumbWidth / 2;
						cursorPoint.y = (height - thumbHeight) / 2 + offset.y
								+ thumbHeight / 2;

						float value = (float) thumbX
								/ (float) (width - thumbWidth);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (this.listener != null)
							this.listener
									.onSeekBarBeginDrag(
											this,progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners
									.get(i)
									.onSeekBarBeginDrag(
											this,progress);

						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_UP
						|| action == MotionEvent.ACTION_CANCEL) {
					if (pressed) {
						pressed = false;
						float value = (float) thumbX
								/ (float) (width - thumbWidth);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (this.listener != null)
							this.listener.onSeekBarDragged(this,progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i)
									.onSeekBarDragged(this,progress);
						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_MOVE) {
					if (pressed) {
						thumbX = (int) (x - thumbDX);
						thumbX = (thumbX < minThumbY)?minThumbY :thumbX > maxThumbX?maxThumbX:thumbX;
						cursorPoint.x = (int)thumbX + offset.x + thumbWidth / 2;
						cursorPoint.y = (height - thumbHeight) / 2 + offset.y
								+ thumbHeight / 2;

						float value = (float) thumbX
								/ (float) (width - thumbWidth);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (listener != null)
							listener.onSeekBarDragging(this, progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i).onSeekBarDragging(this,
									progress);

						parent.invalidate();
						return true;
					}
				}
				break;
			case VERTICAL:
				if (action == MotionEvent.ACTION_DOWN) {
					int additionHeight = (width - thumbHeight) / 2;
					if (thumbY - additionHeight + offset.y <= y
							&& y <= thumbY + offset.y  + thumbHeight + additionHeight 
							&& x >= offset.x
							&& x <= width + offset.x) {
						pressed = true;
						thumbDY = (int) (y - thumbY);
						cursorPoint.x = (width - thumbWidth) / 2 + offset.x
								+ thumbWidth / 2;
						cursorPoint.y = (int)thumbY + offset.y + thumbHeight / 2;

						float value = (float) thumbY
								/ (float) (height - thumbHeight);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (this.listener != null)
							this.listener
									.onSeekBarBeginDrag(
											this,progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners
									.get(i)
									.onSeekBarBeginDrag(
											this,progress);

						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_UP
						|| action == MotionEvent.ACTION_CANCEL) {
					if (pressed) {

						pressed = false;
						if (action == MotionEvent.ACTION_UP) {

							float value = (float) thumbY
									/ (float) (height - thumbHeight);
							this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
									: Math.abs(1f - value);

							if (this.listener != null)
								this.listener.onSeekBarDragged(this,  progress);
							for (int i = 0; i < this.listerners.size(); i++)
								this.listerners.get(i).onSeekBarDragged(this,progress);
						}

						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_MOVE) {
					if (pressed) {
						thumbY = (int) (y - thumbDY);
						thumbY = (thumbY < minThumbY)?minThumbY :thumbY > maxThumbY?maxThumbY:thumbY;
						
						cursorPoint.x = (width - thumbWidth) / 2 + offset.x
								+ thumbWidth / 2;
						cursorPoint.y = (int)thumbY + offset.y + thumbHeight / 2;

						float value = (float) thumbY
								/ (float) (height - thumbHeight);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (listener != null)
							listener.onSeekBarDragging(this, progress);

						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i).onSeekBarDragging(this,
									progress);

						parent.invalidate();
						return true;
					}
				}

				break;
			}
		}
		return false;
	}

	public void drawLine(Canvas canvas) {
		switch (this.direction) {
		case HORIZONTAL:

			if (this.cursor_direction == CURSOR_DIRECTION_L2R) {
				innerRect = new RectF(offset.x
						- (isAppendCursorBG ? half_line_width : 0) + thumbWidth
						/ 2, (height / 2) + offset.y - half_line_width,
						(width - thumbWidth / 2) + offset.x, (height / 2)
								+ half_line_width + offset.y);

				outerRect = new RectF(offset.x
						- (isAppendCursorBG ? half_line_width : 0) + thumbWidth
						/ 2, (height / 2) + offset.y - half_line_width,
						(thumbWidth / 2 + thumbX) + offset.x, (height / 2)
								+ half_line_width + offset.y);

				unusedRect = new RectF((thumbWidth / 2 + maxThumbX) + offset.x,
						(height / 2) + offset.y - half_line_width,
						(width - thumbWidth / 2) + offset.x, (height / 2)
								+ half_line_width + offset.y);

			} else {
				innerRect = new RectF(offset.x
						- (isAppendCursorBG ? half_line_width : 0) + thumbWidth
						/ 2, (height / 2) + offset.y - half_line_width,
						(thumbWidth / 2 + thumbX) + offset.x, (height / 2)
								+ half_line_width + offset.y);

				outerRect = new RectF(offset.x
						- (isAppendCursorBG ? half_line_width : 0) + thumbWidth
						/ 2, (height / 2) + offset.y - half_line_width,
						(width - thumbWidth / 2) + offset.x, (height / 2)
								+ half_line_width + offset.y);

				unusedRect = new RectF(offset.x
						- (isAppendCursorBG ? half_line_width : 0) + thumbWidth
						/ 2, (height / 2) + offset.y - half_line_width,
						(width - thumbWidth / 2) + offset.x, (height / 2)
								+ half_line_width + offset.y);

			}
			if (playing) {
				innerRect.top -= (zoom_anim * innerRect.height() / 2);
				innerRect.bottom += (zoom_anim * innerRect.height() / 2);
				// innerRect.left -= (zoom_anim * innerRect.width()/2);
				// innerRect.right += (zoom_anim * innerRect.width()/2);

				outerRect.top -= (zoom_anim * outerRect.height() / 2);
				outerRect.bottom += (zoom_anim * outerRect.height() / 2);
				// outerRect.left -= (zoom_anim * outerRect.width()/2);
				// outerRect.right += (zoom_anim * outerRect.width()/2);

				unusedRect.top -= (zoom_anim * unusedRect.height() / 2);
				unusedRect.bottom += (zoom_anim * unusedRect.height() / 2);
			}
			break;
		case VERTICAL:
			if (this.cursor_direction == CURSOR_DIRECTION_L2R) {
				innerRect = new RectF((width / 2) + offset.x - half_line_width,
						offset.y + thumbHeight / 2, (width / 2)
								+ half_line_width + offset.x,
						(height - thumbHeight / 2) + offset.y
								+ (isAppendCursorBG ? half_line_width : 0));
				outerRect = new RectF((width / 2) + offset.x - half_line_width,
						offset.y + thumbHeight / 2, (width / 2)
								+ half_line_width + offset.x,
						(thumbHeight / 2 + thumbY) + offset.y
								+ (isAppendCursorBG ? half_line_width : 0));
				unusedRect = new RectF(
						(width / 2) + offset.x - half_line_width, 0,
						(width / 2) + half_line_width + offset.x,
						(height - thumbHeight / 2) + offset.y
								+ (isAppendCursorBG ? half_line_width : 0));

			} else {
				innerRect = new RectF((width / 2) + offset.x - half_line_width,
						offset.y + thumbHeight / 2, (width / 2)
								+ half_line_width + offset.x, (thumbHeight / 2)
								+ thumbY + offset.y);
				outerRect = new RectF((width / 2) + offset.x - half_line_width,
						(thumbHeight / 2) + thumbY + offset.y, (width / 2)
								+ half_line_width + offset.x,
						(height - thumbHeight / 2) + offset.y
								+ (isAppendCursorBG ? half_line_width : 0));
				unusedRect = new RectF(
						(width / 2) + offset.x - half_line_width, offset.y
								+ (thumbHeight / 2), (width / 2)
								+ half_line_width + offset.x, offset.y + minThumbY+ (thumbHeight / 2));

			}
			if (playing) {
				// innerRect.top -= (zoom_anim * innerRect.height()/2);
				// innerRect.bottom += (zoom_anim * innerRect.height()/2);
				innerRect.left -= (zoom_anim * innerRect.width() / 2);
				innerRect.right += (zoom_anim * innerRect.width() / 2);

				// outerRect.top -= (zoom_anim * outerRect.height()/2);
				// outerRect.bottom += (zoom_anim * outerRect.height()/2);
				outerRect.left -= (zoom_anim * outerRect.width() / 2);
				outerRect.right += (zoom_anim * outerRect.width() / 2);

				unusedRect.left -= (zoom_anim * outerRect.width() / 2);
				unusedRect.right += (zoom_anim * outerRect.width() / 2);
			}
			break;
		}
		canvas.drawRect(innerRect, inner);
		canvas.drawRect(outerRect, outer);
		canvas.drawRect(unusedRect, unusedPaint);
	}
    
    public void drawCursor(Canvas canvas)
    {
    	if(this.hideCursor)return;
    	
    	thumb = (!pressed)?thumbDrawable:thumbDrawablePressed;
    	
    	if(thumb==null)return;
    	
    	if(playing)
    		thumb.setAlpha(alpha);
    	
    	switch(this.direction)
    	{
	    	case HORIZONTAL:
				int y = (height - thumbHeight) / 2;
				thumb.setBounds((int)thumbX + offset.x, y + offset.y, (int)thumbX
							+ thumbWidth + offset.x, y + thumbHeight + offset.y);
				thumb.draw(canvas);
	    		break;
	    	case VERTICAL:
				int x = (width - thumbWidth) / 2;
	    	    thumb.setBounds(x + offset.x, (int)thumbY + offset.y, x + thumbWidth + offset.x, (int)thumbY + thumbHeight + offset.y);
	    	    thumb.draw(canvas);
	    		break;
    	}
    }

    public void drawUnit(Canvas canvas)
    {
    	if(this.isShowUnit)
	    	switch(this.direction)
	    	{
		    	case HORIZONTAL:
					if(cursor_direction==CURSOR_DIRECTION_L2R)
						for(int i=0;i<unit_point;i++)
						{
							float x = offset.x - 1.1f + (float)((i*unit_scale)*(width - thumbWidth)) + (thumbWidth/2);
							canvas.drawText(String.format("%."+unitOfFloat+"f",i*unit_scale),x-text_half_width, offset.y + 50, unitPaint);
							canvas.drawText("|", x - bar_half_width,offset.y + 30 , barPaint);
							if(i<unit_point-1)
							{
								x = offset.x  + (float)(((i*unit_scale)+0.05f)*(width - thumbWidth)) + (thumbWidth/2);
								canvas.drawText("|", x - sub_bar_half_width,offset.y + 30 , sub_barPaint);
							}
						}
					else
						for(int i=unit_point;i>=0;i--)
						{
							float x = offset.x - 1.1f + (float)((i*unit_scale)*(width - thumbWidth)) + (thumbWidth/2);
							canvas.drawText(String.format("%."+unitOfFloat+"f",i*unit_scale),x-text_half_width, offset.y + 50, unitPaint);
							canvas.drawText("|", x - bar_half_width,offset.y + 30 , barPaint);
							if(i>1)
							{
								x = offset.x + (float)(((i*unit_scale)+0.05f)*(width - thumbWidth)) + (thumbWidth/2);
								canvas.drawText("|", x - sub_bar_half_width,offset.y + 30 , sub_barPaint);
							}
						}
		    		break;
		    	case VERTICAL:
		    		/*
		    		if(cursor_direction==CURSOR_DIRECTION_L2R)
						for(int i=0;i<unit_point;i++)
						{
							float y = (float)((i*unit_scale)*(height-thumbHeight*2)) + offset.y + thumbHeight;
							canvas.drawText(""+dfm.format(i*unit_scale*weight), offset.x - bar_half_width - 5, y, unitPaint);
							canvas.drawText("_",offset.x - 5 , y, barPaint);
						}
					else
						for(int i=unit_point;i>0;i--)
						{
							float y = (float)((i*unit_scale)*(height-thumbHeight*2)) + offset.y + thumbHeight;
							canvas.drawText(""+dfm.format(i*unit_scale*weight), offset.x - bar_half_width - 5, y-3, unitPaint);
							canvas.drawText("_",offset.x - 5 , y-3, barPaint);
						}
						*/
					break;
	    	}
    }

	public void drawLabel(Canvas canvas)
    {
    	if(!hideLabel&&(pressed||iscoverLabel))
    	{
        	if(playing)
        		labelDrawable.setAlpha(alpha);
    		switch(this.direction)
        	{
    	    	case HORIZONTAL:
    				int y =-5+ (height - labelHeight) / 2;
    				labelDrawable.setBounds((int)thumbX + offset.x - (labelWidth-thumbWidth)/2, y + offset.y- labelHeight/2, (int)thumbX
    							+ (labelWidth+thumbWidth)/2 + offset.x, y  + offset.y+ labelHeight/2);
    				
    				labelDrawable.draw(canvas);
    				String label = String.format("%."+labelOfFloat+"f", (cursor_direction == CURSOR_DIRECTION_L2R) ? progress
								: Math.abs(1f - progress));
    				canvas.drawText(label,thumbX + offset.x - (-thumbWidth+labelPaint.measureText(label))/2,y + offset.y -15/2 , labelPaint);
					break;
    	    	case VERTICAL:
    	    		break;
        	}
    	}
    }
    
	public void drawHand(Canvas canvas)
	{
		if(!hideHand)
    	{
	    	if(playing)
	    		handDrawable.setAlpha(alpha);
			handDrawable.setBounds(getCursorX() - (int)((handWidth*0.55f)/2), getCursorY(), getCursorX() + (int)((handWidth*1.45f)/2), getCursorY() + handHeight);
			handDrawable.draw(canvas);
    	}
	}
}